
public class WinningCombination {
	
	public enum WinningCombinationType {
		HORIZONTAL, VERTICAL, DIAGONALDOWN, DIAGONALUP;
	}
	
	public WinningCombinationType type;
	public Integer positionX;
	public Integer positionY;
	public Boolean[] exists = new Boolean[5];
	
	/**
	 * For Debugging purposes
	 */
	public void print() {
		System.out.println(type);
		System.out.println(positionX);
		System.out.println(positionY);
		for (int i = 0; i < 5; i++) {
			System.out.println(exists[i]);
		}
	}
	
	public WinningCombination(Integer positionX, Integer positionY, WinningCombinationType type) {
		this.positionX = positionX;
		this.positionY = positionY;
		this.type = WinningCombinationType.values()[type.ordinal()];
	}
	
	public void mark(Integer moveX, Integer moveY) throws Exception {
		for (int i = 0; i < 5; i++) {
			if (positionX == moveX && positionY == moveY) {
				exists[i] = true;
				return;
			}
			switch (type) {
				case HORIZONTAL:
					moveX--;
					break;
				case VERTICAL:
					moveY--;
					break;
				case DIAGONALUP:
					moveX--;
					moveY++;
					break;
				case DIAGONALDOWN:
					moveX--;
					moveY--;
					break;
			}
		}
		throw new Exception("Nothing to mark");
		
	}
	
	public WinningCombination clone() {
		WinningCombination clone = new WinningCombination(this.positionX, this.positionY, this.type);
		for (int i = 0; i < 5; i++) {
			clone.exists[i] = this.exists[i];
		}
		return clone;
	}
	
	public boolean contains(Integer moveX, Integer moveY) {
		for (int i = 0; i < 5; i++) {
			if (positionX == moveX && positionY == moveY) {
				return true;
			}
			switch (type) {
				case HORIZONTAL:
					moveX--;
					break;
				case VERTICAL:
					moveY--;
					break;
				case DIAGONALUP:
					moveX--;
					moveY++;
					break;
				case DIAGONALDOWN:
					moveX--;
					moveY--;
					break;
			}
		}
		return false;
	}
	
	public int element(Integer moveX, Integer moveY) throws Exception {
		if (!contains(moveX, moveY)) {
			throw new Exception("Move is not inside this winning combination");
		}
		for (int i = 0; i < 5; i++) {
			if (positionX == moveX && positionY == moveY) {
				return i;
			}
			switch (type) {
				case HORIZONTAL:
					moveX--;
					break;
				case VERTICAL:
					moveY--;
					break;
				case DIAGONALUP:
					moveX--;
					moveY++;
					break;
				case DIAGONALDOWN:
					moveX--;
					moveY--;
					break;
			}
		}
		return 0;
	}

	public boolean straightFive() {
		return (exists[0] != null && exists[0] == true && 
				exists[1] != null && exists[1] == true && 
				exists[2] != null && exists[2] == true &&
				exists[3] != null && exists[3] == true && 
				exists[4] != null && exists[4] == true);
	}
	
	public boolean straightFour() {
		if (exists[0] == null || exists[0] == false) {
			return (exists[1] != null && exists[1] == true && 
					exists[2] != null && exists[2] == true && 
					exists[3] != null && exists[3] == true && 
					exists[4] != null && exists[4] == true);
		} else {
			return (exists[1] != null && exists[1] == true && 
					exists[2] != null && exists[2] == true && 
					exists[3] != null && exists[3] == true);
		}
	}
	
	public int count() {
		int count = 0;
		for (int i = 0; i < 5; i++) {
			if (exists[i] != null && exists[i] == true) {
				count++;
			}
		}
		return count;
	}
	
	public boolean hasFour() {
		if (count() >= 4) {
			return true;
		} else {
			return false;
		}
	}
	
	public boolean hasThree() {
		if (count() >= 3) {
			return true;
		} else {
			return false;
		}
			
	}
	
	public boolean straightThree() {
		if (straightFour()) {
			return false;
		} else {
			if (hasThree()) {
				return ((exists[0] != null && exists[0] == true && 
							exists[1] != null && exists[1] == true && 
							exists[2] != null && exists[2] == true) ||
						(exists[1] != null && exists[1] == true &&
							exists[2] != null && exists[2] == true && 
							exists[3] != null && exists[3] == true) ||
						(exists[2] != null && exists[2] == true && 
							exists[3] != null && exists[3] == true && 
							exists[4] != null && exists[4] == true));
			} else {
				return false;
			}
		}
	
	}
	
}
